package com.centit.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.centit.framework.components.CodeRepositoryUtil;
import java.net.URLEncoder;
public class ZipUtil {

	private static final Log log = LogFactory.getLog(ZipUtil.class);

	/**
     * 使用UTF-8编码可以避免压缩中文文件名乱码
     */
    private static final String CHINESE_CHARSET = "UTF-8";

    /**
     * 文件读取缓冲区大小
     */
    private static final int CACHE_SIZE = 1024;


    /**
     * 文件下载
     * @param urlsrc 下载请求路径
     * @param outpath   文件放置路径
     * @throws UnknownHostException
     */
    public static void DownLoadPages(String urlsrc, String outpath) throws UnknownHostException{
        // 输入流
        InputStream in = null;
        // 文件输出流
        FileOutputStream out = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(urlsrc);
        CloseableHttpResponse response = null;
        try{
            response = httpClient.execute(get);
            HttpEntity entity = response.getEntity(); // 获取响应里面的内容
            in = entity.getContent(); // 得到服务气端发回的响应的内容（都在一个流里面）
            out = new FileOutputStream(new File(outpath));
            byte[] b = new byte[1024];
            int len = 0;
            while((len=in.read(b))!= -1){
                out.write(b,0,len);
            }
            in.close();
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("download, success!!");
    }

    /**
     * 根据文件服务器路径获取文件名 让下载的文件名和文件服务器上的文件名相同
     * @param outPath 文件夹名
     * @param eenclosure    文件id
     * @throws UnknownHostException
     */
    public  static void downByUrlsrcTooutPath(String outPath,String eenclosure,String userCodeName) throws UnknownHostException, UnsupportedEncodingException {
        if(StringUtils.isNotBlank(eenclosure)&&!"undefined".equals(eenclosure)) {
    	    // 保持与生产一致，本地环境修改请勿提交
        	//获取文件名
            //String result = HttpRequest.sendRestGet(CodeRepositoryUtil.getSysConfigValue("webserviceLocalUploaderpath")+"/service/files",eenclosure);
            String result = HttpRequest.sendRestGet(CodeRepositoryUtil.getSysConfigValue("uploaderpath")+"/service/files",eenclosure);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String filename = ((JSONObject)jsonObject.get("data")).get("fileName").toString();//拼接下载链接
            //String urlsrc=CodeRepositoryUtil.getSysConfigValue("webserviceLocalUploaderpath")+"/service/download/pfile/"+eenclosure; //要访问的链接
            String urlsrc=CodeRepositoryUtil.getSysConfigValue("uploaderpath")+"/service/download/pfile/"+eenclosure; //要访问的链接
            outPath=outPath+"\\"+userCodeName+"-"+filename; //本地路径
            DownLoadPages(urlsrc,outPath);
        }
    }

    /**
     * 循环下载文件
     * @param dir
     * @param eenclosures
     * @param userCode
     */
    public static String alldown(String dir, Map<String,String> eenclosures, String userCode) throws Exception {
        Date date = new Date();
        String sjc = date.getTime()+"";
        String homwPath = CodeRepositoryUtil.getSysConfigValue("ziphomepath");
        File file1 = new File(homwPath);
        if(!file1.exists()){
            file1.mkdir();
        }
        String strPath = homwPath+"\\"+dir+userCode+sjc;
        File file = new File(strPath);
        if(!file.exists()){
            file.mkdir();
        }
        for (String encl:eenclosures.keySet()) {
            try {
                downByUrlsrcTooutPath(strPath,encl,eenclosures.get(encl));
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
        String zipPath = zipDirectory(strPath);
        System.out.println(zipPath);
        delDir(strPath);
        return zipPath;
    }


    /**
     * 压缩一个文件夹
     *
     * @throws IOException
     */
    public static String zipDirectory(String path) throws IOException {
        File file = new File(path);
        String parent = file.getParent();
        String zipName = file.getName() + ".zip";
        File zipFile = new File(parent,zipName);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
        zip(zos, file, file.getName());
        zos.flush();
        zos.close();
        return path+".zip";
    }
    
    /**
     * 压缩一个文件夹
     *
     * @throws IOException
     */
    public static String zipDirectory(String path,String outName) throws IOException {
        File file = new File(path);
        String parent = file.getParent();
        String zipName = outName + ".zip";
        File zipFile = new File(parent,zipName);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
        zip(zos, file, file.getName());
        zos.flush();
        zos.close();
        return parent+zipName;
    }

    /**
     *
     * @param zos
     *            压缩输出流
     * @param file
     *            当前需要压缩的文件
     * @param path
     *            当前文件相对于压缩文件夹的路径
     * @throws IOException
     */
    private static void zip(ZipOutputStream zos, File file, String path) throws IOException {
        // 首先判断是文件，还是文件夹，文件直接写入目录进入点，文件夹则遍历
        if (file.isDirectory()) {
            ZipEntry entry = new ZipEntry(path + File.separator);// 文件夹的目录进入点必须以名称分隔符结尾
            zos.putNextEntry(entry);
            File[] files = file.listFiles();
            for (File x : files) {
                zip(zos, x, path + File.separator + x.getName());
            }
        } else {
            FileInputStream fis = new FileInputStream(file);// 目录进入点的名字是文件在压缩文件中的路径
            ZipEntry entry = new ZipEntry(path);
            zos.putNextEntry(entry);// 建立一个目录进入点
            zos.setEncoding("GBK");
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = fis.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.flush();
            fis.close();
            zos.closeEntry();// 关闭当前目录进入点，将输入流移动下一个目录进入点
        }
    }

    /**
     * 删除下载的文件夹
     * @param path
     */
    public static void delDir(String path){
        File dir=new File(path);
        if(dir.exists()){
            File[] tmp=dir.listFiles();
            for(int i=0;i<tmp.length;i++){
                if(tmp[i].isDirectory()){
                    delDir(path+"/"+tmp[i].getName());
                }
                 else{
                    tmp[i].delete();
                }
            }
            dir.delete();
        }
    }

    public static String dowmByJSONArray(String dir , JSONArray jsonArray,String usercode) throws Exception {
        Map<String,String> map = new HashMap<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            if(jsonArray.getJSONObject(i).get("enclosure") != null){
                String enclosure = jsonArray.getJSONObject(i).get("enclosure").toString();
                if(enclosure != null && !"".equals(enclosure)){
                    String[] split = enclosure.split(",");
                    for (String enclo: split) {
                        map.put(enclo,jsonArray.getJSONObject(i).get("unitName").toString());
                    }
                }
            }
            if(jsonArray.getJSONObject(i).get("fj") != null){
                String fj = jsonArray.getJSONObject(i).get("fj").toString();
                if(fj != null && !"".equals(fj)){
                    String[] split = fj.split(",");
                    for (String f: split) {
                        map.put(f,jsonArray.getJSONObject(i).get("unitName").toString());
                    }
                }
            }
        }
        return alldown(dir,map,usercode);
    }

    public static void exportZip(String dir , JSONArray jsonArray,String usercode,HttpServletRequest request, HttpServletResponse response) throws IOException {
        FileInputStream in = null;
        OutputStream out = null;
        File file = null;
        try {
            String realpath = dowmByJSONArray(dir,jsonArray,usercode);
            file = new File(realpath);
            if(!file.exists()){
                request.setAttribute("message", "您要下载的资源已被删除！！");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return;
            }
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            response.setHeader("Content-Length", ""+file.length());
            in = new FileInputStream(realpath);
            out = response.getOutputStream();
            byte buffer[] = new byte[1024];
            int len = 0;
            //循环将输入流中的内容读取到缓冲区当中
            while((len=in.read(buffer))>0){
                //输出缓冲区的内容到浏览器，实现文件下载
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭文件输入流
            in.close();
            //关闭输出流
            out.close();
            file.delete();
        }
    }

    /*public static void main(String[] args) throws Exception {
       //* String result = HttpRequest.sendRestGet(CodeRepositoryUtil.getSysConfigValue("uploaderpath")+"/service/files","8a89800a675ccfab016775379f090147");
        String result = HttpRequest.sendRestGet(CodeRepositoryUtil.getSysConfigValue("uploaderpath")+"/service/files","bb5a794b7114b2b9017180f4466e0062");
        JSONObject jsonObject = JSONObject.parseObject(result);
        String filename = ((JSONObject)jsonObject.get("data")).get("fileName").toString();
        String urlsrc="http://10.9.0.203/product-file/service/download/pfile/bb5a794b7114b2b9017180f4466e0062"; //要访问的链接
        String outPath="D:\\zip\\"+filename; //本地路径
        DownLoadPages(urlsrc,outPath);


        List<String> ecs = new ArrayList<>();
        ecs.add("8a89800a675ccfab016775379f090147");
        ecs.add("8a89800a675ccfab01677fe34e2205e2");
        ecs.add("8a89800a675ccfab01677fe3614d05e3");
        alldown("A1-7",ecs,"UD0001");

    }*/
    
    
    /**
     * 东航机队信息  相关文件导出
     * @param jsonArray
     * @param list
     * @throws IOException 
     */
    public static void creartDir(JSONArray jsonArray,JSONArray list,HttpServletResponse response) throws IOException {
    	File fd = null;  
    	for (int i = 0; i < jsonArray.size(); i++) {
    		//遍历飞机信息列表
    		JSONObject jsonObject = jsonArray.getJSONObject(i);
    		//根据飞机sign 创建文件夹
    		String dirName = jsonObject.getString("sign");
    		String path="D:\\zip\\"+dirName;
    		fd = new File(path);  
            if (!fd.exists()) {  
                fd.mkdirs();  
            } 
    		for (int j = 0; j < list.size(); j++) {
    			//遍历需要下载的文件列
    			JSONObject jsonkey = list.getJSONObject(j);
    			//获取对应的文件ids
    			String fileIdString = jsonObject.getString(jsonkey.getString("value"));
    			try {
    				if(StringUtils.isNotBlank(fileIdString)) {
        				//可能是多个文件 id用逗号隔开
        				String[] fileIds = fileIdString.split(",");
        				for(int k = 0 ; k < fileIds.length ; k++) {
        					//设置对应的文件名称
        					String fileName = jsonObject.getString("sign")+jsonkey.getString("name");
        					downByUrlsrcTooutPath(path,fileIds[k],fileName);
        				}
        			}
    			} catch (Exception e) {
    				System.out.println("出现错误了！");
					continue;
				}
    		}
		}
    	String zipPath = "";
    	try {
			 zipPath = zipDirectory("D:\\zip","各类证书");
			 System.out.println(zipPath);
			 delDir("D:\\zip");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	FileInputStream in = null;
        OutputStream out = null;
        File file = null;
        try {
            file = new File(zipPath);
            if(!file.exists()){
                /*request.setAttribute("message", "您要下载的资源已被删除！！");
                request.getRequestDispatcher("/message.jsp").forward(request, response);*/
                return;
            }
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            response.setHeader("Content-Length", ""+file.length());
            in = new FileInputStream(zipPath);
            out = response.getOutputStream();
            byte buffer[] = new byte[1024];
            int len = 0;
            //循环将输入流中的内容读取到缓冲区当中
            while((len=in.read(buffer))>0){
                //输出缓冲区的内容到浏览器，实现文件下载
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭文件输入流
            in.close();
            //关闭输出流
            out.close();
            file.delete();
        }
    }

}
